// Array 获取最后一个元素的下标
Object.defineProperty(Array.prototype, 'lastIdx', {
  value: function () {
    return this.length - 1
  },
  enumerable: false,
  writable: false,
  configurable: true,
});
// Array 获取最后一个元素
Object.defineProperty(Array.prototype, 'last', {
  value: function () {
    return this[this.length - 1]
  },
  enumerable: false,
  writable: false,
  configurable: true,
});
// Array 获取最后一个元素
Object.defineProperty(Array.prototype, 'count', {
  value: function (val) {
    const a = typeof val === 'function'
      ? val
      : typeof val === 'object'
        ? (i) => !Object.keys(val).map(o => i[o] === val[o]).has(false)
        : (i) => i === val

    return this.filter(a).length
  },
  enumerable: false,
  writable: false,
  configurable: true,
});
// Array 判断是否存在
Object.defineProperty(Array.prototype, 'has', {
  value: function (value) {
    let bool = false
    if (typeof value === 'function') {
      for (let i = 0; i < this.length; i++) {
        const res = value(this[i], i)
        if (res) {
          bool = true
          break
        }
      }
      return bool
    } else return this.includes(value)
    // return new Set(this).has(value);
  },
  enumerable: false,
  writable: false,
  configurable: true,
});
// Array 数字求和
Object.defineProperty(Array.prototype, 'sum', {
  value: function () {
    return this.reduce((prev, curr) => prev + curr, 0);
  },
  enumerable: false,
  writable: false,
  configurable: true,
});
// Array 内部处理 消除/填补
Object.defineProperty(Array.prototype, 'invert', {
  value: function (val) {
    let index = -1
    if (typeof val === 'function') index = this.findIndex(val)
    else index = this.indexOf(val)
    // ====================================
    if (index > -1) this.splice(index, 1)
    else {
      this.push(val)
    }
    return this
  },
  enumerable: false,
  writable: false,
  configurable: true,
});
// Array 内部处理 按指定的key排序
Object.defineProperty(Array.prototype, 'sortBy', {
  value: function (key, flag) {
    if (!key) {
      console.error('[Array.sortBy( key , flag )] need params key')
      return this
    }
    if (this.length > 0) {
      if (typeof this[0][key] === 'number') {
        if (flag && flag === 'DESC') {
          this.sort((a, b) => b[key] - a[key])
        } else {
          // console.log('升序')
          this.sort((a, b) => a[key] - b[key])
        }
      } else {
        console.error(`[Array] item key '${key}' typeof is not 'number' `)
      }
    }
    return this
  },
  enumerable: false,
  writable: false,
  configurable: true,
});
// Set 复制为新的
Object.defineProperty(Set.prototype, 'copy', {
  value: function () {
    return new Set(Array.from(this))
  },
  enumerable: false,
  writable: false,
  configurable: true,
});
// Set 内部处理 取反
Object.defineProperty(Set.prototype, 'invert', {
  value: function (val) {
    if (this.has(val)) this.delete(val)
    else this.add(val)
    return this
  },
  enumerable: false,
  writable: false,
  configurable: true,
});
// Set 内部处理 异或
Object.defineProperty(Set.prototype, 'xor', {
  value: function (val, bool) {
    if (this.has(val) !== bool) this.invert(val)
    return this
  },
  enumerable: false,
  writable: false,
  configurable: true,
});
// Date 按字段更新到开始的时间
Object.defineProperty(Date.prototype, 'startOf', {
  value: function (key) {
    if (!key) {
      console.error('[funcation Date.startOf]: params "key" is must')
      return
    }
    const BEGIN_DAY = () => {
      this.setHours(0)
      this.setMinutes(0)
      this.setSeconds(0)
    }
    switch (key) {
      case 'day':
        BEGIN_DAY()
        break;
      case 'month':
        this.setDate(1)
        BEGIN_DAY()
        break;
      case 'year':
        this.setMonth(0)
        this.setDate(1)
        BEGIN_DAY()
        break;
      default:
        console.error('[funcation Date.startOf]: "key" value disabled')
    }
    return this
  },
  enumerable: false,
  writable: false,
  configurable: true,
})
// Date 按字段更新到结束的时间
Object.defineProperty(Date.prototype, 'endOf', {
  value: function (key) {
    if (!key) {
      console.error('[funcation Date.endOf]: params "key" is must')
      return
    }
    const END_DAY = () => {
      this.setHours(23)
      this.setMinutes(59)
      this.setSeconds(59)
    }
    switch (key) {
      case 'day':
        END_DAY()
        break;
      case 'month':
        this.setMonth(this.getMonth() + 1)
        this.setDate(0)
        END_DAY()
        break;
      case 'year':
        this.setMonth(12)
        this.setDate(0)
        END_DAY()
        break;
      default:
        console.error('[funcation Date.endOf]: "key" value disabled')
    }
    return this
  },
  enumerable: false,
  writable: false,
  configurable: true,
})
Object.defineProperty(Object.prototype, 'getKeys', {
  value: function (keys) {
    if (!keys || keys.length === 0) return this
    const obj = {}
    const keyArr = keys.split(',')
    // console.log(this)
    Object.keys(this).forEach(i => keyArr.includes(i) && (obj[i] = this[i]))
    return obj
  },
  enumerable: false,
  writable: false,
  configurable: true,
});
Object.defineProperty(Object.prototype, 'getKeysArr', {
  value: function (keys) {
    if (!keys || keys.length === 0) return this
    const Arr = []
    const keyArr = keys.split(',')
    // console.log(this)
    keyArr.forEach(i => {
      if (this[i]) Arr.push(this[i])
    })
    return Arr
  },
  enumerable: false,
  writable: false,
  configurable: true,
});

